﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;

namespace DataCopy
{
    public partial class frmMain : Form
    {
        Dictionary<string, Column[]> _tables = new Dictionary<string, Column[]>();

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            CreateTable();

            ColumnFill();

            if (!string.IsNullOrEmpty(Program.Session[Settings.Sure].ToString()))
            {
                timer1.Interval = Cevir.Parse<int>(Program.Session[Settings.Sure]) * 1000;
                timer1.Enabled = true;
                timer1.Start();
            }
        }

        private void ColumnFill()
        {
            DataTable dt = DataLayer.Get.Fill("select COLUMN_NAME,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='CARI_HESAP_HAREKETLERI' AND ORDINAL_POSITION > 1 ORDER BY ORDINAL_POSITION");
            List<Column> _cols = new List<Column>();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][1].ToString() == "3")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "-1" });
                }
                else if (dt.Rows[i][0].ToString() == "cha_tip")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "@Tip" });
                }
                else if (dt.Rows[i][0].ToString() == "cha_evrak_tip")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "@evrakTip" });
                }
                else
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "" });
                }
            }
            _tables.Add("CARI_HESAP_HAREKETLERI", _cols.ToArray());


            dt = DataLayer.Get.Fill("select COLUMN_NAME,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='STOK_HAREKETLERI' AND ORDINAL_POSITION > 1 ORDER BY ORDINAL_POSITION");
            _cols.Clear();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][1].ToString() == "3")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "-1" });
                }
                else if (dt.Rows[i][0].ToString() == "sth_tip")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "@Tip" });
                }
                else if (dt.Rows[i][0].ToString() == "sth_evraktip")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "@evrakTip" });
                }
                else if (dt.Rows[i][0].ToString() == "sth_fat_recid_recno")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "@charID" });
                }
                else
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "" });
                }
            }
            _tables.Add("STOK_HAREKETLERI", _cols.ToArray());

            dt = DataLayer.Get.Fill("select COLUMN_NAME,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='STOKLAR' AND ORDINAL_POSITION > 1 ORDER BY ORDINAL_POSITION");
            _cols.Clear();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][1].ToString() == "3")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "-1" });
                }
                else
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "" });
                }
            }
            _tables.Add("STOKLAR", _cols.ToArray());

            dt = DataLayer.Get.Fill("select COLUMN_NAME,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='BARKOD_TANIMLARI' AND ORDINAL_POSITION > 1 ORDER BY ORDINAL_POSITION");
            _cols.Clear();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i][1].ToString() == "3")
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "-1" });
                }
                else
                {
                    _cols.Add(new Column() { Name = dt.Rows[i][0].ToString(), Value = "" });
                }
            }
            _tables.Add("BARKOD_TANIMLARI", _cols.ToArray());
        }

        private void CreateTable()
        {
            DataLayer.Get.Exec("if not exists(select * FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = N'AKTARILANLAR') CREATE TABLE [dbo].[AKTARILANLAR]([kaynak_char_id] [int] NOT NULL,[hedef_char_id] [int] NOT NULL,CONSTRAINT [PK_AKTARILANLAR] PRIMARY KEY CLUSTERED ([kaynak_char_id] ASC,[hedef_char_id] ASC) WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]) ON [PRIMARY]");
        }

        private void CheckedAktarildi(int kaynak_char_id, int hedef_char_id)
        {
            DataLayer.Get.Exec(string.Format("if not exists(SELECT     hedef_char_id  FROM         AKTARILANLAR  WHERE     (kaynak_char_id = {0})) INSERT INTO AKTARILANLAR  (kaynak_char_id,hedef_char_id)  VALUES     ({0}, {1})", kaynak_char_id, hedef_char_id));
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!backgroundWorker1.IsBusy)
            {
                timer1.Stop();
                timer1.Enabled = false;
                backgroundWorker1.WorkerSupportsCancellation = true;
                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Dictionary<string, SqlBatch[]> batch = new Dictionary<string, SqlBatch[]>();
            List<SqlBatch> _lst = new List<SqlBatch>();

            //vt1
            DataTable chdt = CharList(Program.Session[Settings.Vt1KaynakCari].ToString(), Program.Session[Settings.Vt1HedefCari].ToString());
            for (int i = 0; i < chdt.Rows.Count; i++)
            {
                _lst.Add(new SqlBatch()
                {
                    CharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["CARI_HESAP_HAREKETLERI"], "CARI_HESAP_HAREKETLERI", true, chdt.Rows[i]),
                    SharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["STOK_HAREKETLERI"], "STOK_HAREKETLERI", false, SharList(Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"]), Program.Session[Settings.Vt1HedefCari].ToString(), Cevir.Parse<string>(chdt.Rows[i]["cha_evrakno_seri"]), Cevir.Parse<int>(chdt.Rows[i]["cha_evrakno_sira"]))),
                    CharId = Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"])
                });
            }
            batch.Add(Program.Session[Settings.Vt1Name].ToString(), _lst.ToArray());
            _lst.Clear();

            //vt2
            chdt = CharList(Program.Session[Settings.Vt2KaynakCari].ToString(), Program.Session[Settings.Vt2HedefCari].ToString());
            for (int i = 0; i < chdt.Rows.Count; i++)
            {
                _lst.Add(new SqlBatch()
                {
                    CharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["CARI_HESAP_HAREKETLERI"], "CARI_HESAP_HAREKETLERI", true, chdt.Rows[i]),
                    SharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["STOK_HAREKETLERI"], "STOK_HAREKETLERI", false, SharList(Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"]), Program.Session[Settings.Vt2HedefCari].ToString(), Cevir.Parse<string>(chdt.Rows[i]["cha_evrakno_seri"]), Cevir.Parse<int>(chdt.Rows[i]["cha_evrakno_sira"]))),
                    CharId = Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"])
                });
            }
            batch.Add(Program.Session[Settings.Vt2Name].ToString(), _lst.ToArray());
            _lst.Clear();


            //vt3
            chdt = CharList(Program.Session[Settings.Vt3KaynakCari].ToString(), Program.Session[Settings.Vt3HedefCari].ToString());
            for (int i = 0; i < chdt.Rows.Count; i++)
            {
                _lst.Add(new SqlBatch()
                {
                    CharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["CARI_HESAP_HAREKETLERI"], "CARI_HESAP_HAREKETLERI", true, chdt.Rows[i]),
                    SharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["STOK_HAREKETLERI"], "STOK_HAREKETLERI", false, SharList(Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"]), Program.Session[Settings.Vt3HedefCari].ToString(), Cevir.Parse<string>(chdt.Rows[i]["cha_evrakno_seri"]), Cevir.Parse<int>(chdt.Rows[i]["cha_evrakno_sira"]))),
                    CharId = Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"])
                });
            }
            batch.Add(Program.Session[Settings.Vt3Name].ToString(), _lst.ToArray());
            _lst.Clear();

            //vt4
            chdt = CharList(Program.Session[Settings.Vt4KaynakCari].ToString(), Program.Session[Settings.Vt4HedefCari].ToString());
            for (int i = 0; i < chdt.Rows.Count; i++)
            {
                _lst.Add(new SqlBatch()
                {
                    CharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["CARI_HESAP_HAREKETLERI"], "CARI_HESAP_HAREKETLERI", true, chdt.Rows[i]),
                    SharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["STOK_HAREKETLERI"], "STOK_HAREKETLERI", false, SharList(Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"]), Program.Session[Settings.Vt4HedefCari].ToString(), Cevir.Parse<string>(chdt.Rows[i]["cha_evrakno_seri"]), Cevir.Parse<int>(chdt.Rows[i]["cha_evrakno_sira"]))),
                    CharId = Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"])
                });
            }
            batch.Add(Program.Session[Settings.Vt4Name].ToString(), _lst.ToArray());
            _lst.Clear();


            //vt5
            chdt = CharList(Program.Session[Settings.Vt5KaynakCari].ToString(), Program.Session[Settings.Vt5HedefCari].ToString());
            for (int i = 0; i < chdt.Rows.Count; i++)
            {
                _lst.Add(new SqlBatch()
                {
                    CharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["CARI_HESAP_HAREKETLERI"], "CARI_HESAP_HAREKETLERI", true, chdt.Rows[i]),
                    SharSql = SqlScriptGenerator.GenerateSqlInserts(_tables["STOK_HAREKETLERI"], "STOK_HAREKETLERI", false, SharList(Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"]), Program.Session[Settings.Vt5HedefCari].ToString(), Cevir.Parse<string>(chdt.Rows[i]["cha_evrakno_seri"]), Cevir.Parse<int>(chdt.Rows[i]["cha_evrakno_sira"]))),
                    CharId = Cevir.Parse<int>(chdt.Rows[i]["cha_RECid_RECno"])
                });
            }
            batch.Add(Program.Session[Settings.Vt5Name].ToString(), _lst.ToArray());
            _lst.Clear();

            FaturaEkle(batch);


            #region Stok Aktarımı

            DataTable dt = DataLayer.Get.Fill(string.Format("SELECT * FROM STOKLAR where (sto_kod not in (select sto_kod from {0}.dbo.STOKLAR))", Program.Session[Settings.Vt1Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["STOKLAR"], "STOKLAR", false, dt), Program.Session[Settings.Vt1Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM STOKLAR where (sto_kod not in (select sto_kod from {0}.dbo.STOKLAR))", Program.Session[Settings.Vt2Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["STOKLAR"], "STOKLAR", false, dt), Program.Session[Settings.Vt2Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM STOKLAR where (sto_kod not in (select sto_kod from {0}.dbo.STOKLAR))", Program.Session[Settings.Vt3Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["STOKLAR"], "STOKLAR", false, dt), Program.Session[Settings.Vt3Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM STOKLAR where (sto_kod not in (select sto_kod from {0}.dbo.STOKLAR))", Program.Session[Settings.Vt4Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["STOKLAR"], "STOKLAR", false, dt), Program.Session[Settings.Vt4Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM STOKLAR where (sto_kod not in (select sto_kod from {0}.dbo.STOKLAR))", Program.Session[Settings.Vt5Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["STOKLAR"], "STOKLAR", false, dt), Program.Session[Settings.Vt5Name].ToString(), null);
            }

            #endregion


            #region Barkod Aktarımı

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM BARKOD_TANIMLARI where (bar_kodu not in (select bar_kodu from {0}.dbo.BARKOD_TANIMLARI))", Program.Session[Settings.Vt1Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["BARKODLAR"], "BARKODLAR", false, dt), Program.Session[Settings.Vt1Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM BARKOD_TANIMLARI where (bar_kodu not in (select bar_kodu from {0}.dbo.BARKOD_TANIMLARI))", Program.Session[Settings.Vt2Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["BARKODLAR"], "BARKODLAR", false, dt), Program.Session[Settings.Vt2Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM BARKOD_TANIMLARI where (bar_kodu not in (select bar_kodu from {0}.dbo.BARKOD_TANIMLARI))", Program.Session[Settings.Vt3Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["BARKODLAR"], "BARKODLAR", false, dt), Program.Session[Settings.Vt3Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM BARKOD_TANIMLARI where (bar_kodu not in (select bar_kodu from {0}.dbo.BARKOD_TANIMLARI))", Program.Session[Settings.Vt4Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["BARKODLAR"], "BARKODLAR", false, dt), Program.Session[Settings.Vt4Name].ToString(), null);
            }

            dt = DataLayer.Get.Fill(string.Format("SELECT * FROM BARKOD_TANIMLARI where (bar_kodu not in (select bar_kodu from {0}.dbo.BARKOD_TANIMLARI))", Program.Session[Settings.Vt5Name].ToString()));
            dt.Columns.RemoveAt(0);
            if (dt.Rows.Count > 0)
            {
                DataLayer.Get.Exec(SqlScriptGenerator.GenerateSqlInserts(_tables["BARKODLAR"], "BARKODLAR", false, dt), Program.Session[Settings.Vt5Name].ToString(), null);
            }

            #endregion



        }

        private void FaturaIns(SqlBatch sql, string db)
        {
            try
            {
                int charId = DataLayer.Get.ExecScalar<int>(sql.CharSql, db, null);
                DataLayer.Get.Exec(sql.SharSql, db, new SqlParameter("@charID", charId));
                CheckedAktarildi(sql.CharId, charId);
            }
            catch (Exception ex)
            {
                using (StreamWriter sw = new StreamWriter(Application.StartupPath + "\\hata.txt", true))
                {
                    sw.WriteLine("------------------------------------------------------------------------BAŞLANGIÇ---------------------------------------------------------------------------------" + DateTime.Now.ToLongDateString());
                    sw.WriteLine(sql.CharSql);
                    sw.WriteLine("------------------------------------------");
                    sw.WriteLine(sql.SharSql);
                    sw.WriteLine("------------------------------------------");
                    sw.WriteLine(ex.Message);
                    sw.WriteLine("------------------------------------------------------------------------SON----------------------------------------------------------------------------------");
                    sw.Close();
                }
            }
        }
        private void FaturaEkle(Dictionary<string, SqlBatch[]> batch)
        {
            try
            {
                foreach (var bt in batch)
                {
                    foreach (var sql in bt.Value)
                    {
                        if (!string.IsNullOrEmpty(sql.CharSql) && !string.IsNullOrEmpty(sql.SharSql))
                        {
                            FaturaIns(sql, bt.Key);
                        }
                        else
                        {
                            CheckedAktarildi(sql.CharId, -1);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private DataTable SharList(int charID, string cariKod, string seri, int sira)
        {
            DataTable dt = DataLayer.Get.Fill(string.Format("exec sp_executesql N'SELECT * FROM STOK_HAREKETLERI WITH ( NOLOCK , INDEX = NDX_STOK_HAREKETLERI_07 )  WHERE (sth_fat_recid_dbcno=0 AND sth_fat_recid_recno={0}) ORDER BY sth_fat_recid_dbcno ASC,sth_fat_recid_recno ASC'", charID));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                dt.Rows[i]["sth_cari_kodu"] = cariKod;
                dt.Rows[i]["sth_evrakno_seri"] = seri;
                dt.Rows[i]["sth_evrakno_sira"] = sira;
                dt.Rows[i]["sth_satirno"] = i;
            }
            dt.Columns.RemoveAt(0);
            return dt;
        }

        private DataTable CharList(string ArananCari, string olacakCari)
        {
            DataTable dt = DataLayer.Get.Fill(string.Format("exec sp_executesql N'SELECT * FROM CARI_HESAP_HAREKETLERI WHERE (cha_ciro_cari_kodu = ''{0}'') AND ((cha_evrak_tip=63 and cha_normal_Iade=0) or (cha_evrak_tip=0 and cha_normal_Iade=1) ) AND (cha_RECid_RECno NOT IN (SELECT     kaynak_char_id FROM AKTARILANLAR))'", ArananCari));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i]["cha_kod"].ToString() == ArananCari)
                {
                    dt.Rows[i]["cha_kod"] = olacakCari;
                }
                dt.Rows[i]["cha_ciro_cari_kodu"] = olacakCari;
            }
            dt.Columns.RemoveAt(0);
            return dt;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            timer1.Enabled = true;
            timer1.Start();
        }

        private void ayarlarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmAyarlar ayar = new frmAyarlar();
            if (ayar.ShowDialog() == DialogResult.OK)
            {
                MessageBox.Show("Program Kapatılıyor...tekrar çalıştırın");
                Application.Exit();
            }
        }

        private void çıkışToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Program.Session.CloseSession();
            backgroundWorker1.CancelAsync();
            Application.Exit();
        }

        private void frmMain_Activated(object sender, EventArgs e)
        {
            this.Hide();
        }
    }
}
